package com.hhf.ftp.shell;

import com.hhf.ftp.service.BaseConst;
import com.hhf.ftp.service.FtpFactory;
import com.hhf.ftp.service.FtpService;
import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.shell.jline.PromptProvider;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;

import java.io.IOException;

@ShellComponent
public class FtpShell implements PromptProvider {
    @Autowired
    private FtpFactory ftpFactory;

    private FtpService ftpService;

    private String connType;

    @ShellMethod("Input username password ip port.")
    public String ftp(String username, String password, String ip, Integer port) throws IOException {
        connType = BaseConst.FTP;
        ftpService = ftpFactory.getFtpService(BaseConst.FTP);
        ftpService.connection(username, password, ip, port);
        return "FTP connection success!";
    }
    @ShellMethod("Input username password ip port.")
    public String ftps(String username, String password, String ip, Integer port) throws IOException {
        connType = BaseConst.FTPS;
        ftpService = ftpFactory.getFtpService(BaseConst.FTPS);
        ftpService.connection(username, password, ip, port);
        return "FTPS connection success!";
    }
    @ShellMethod("Input username password ip port.")
    public String sftp(String username, String password, String ip, Integer port) throws IOException {
        connType = BaseConst.SFTP;
        ftpService = ftpFactory.getFtpService(BaseConst.SFTP);
        ftpService.connection(username, password, ip, port);
        return "SFTP connection success!";
    }
    @ShellMethod("Input username password ip port.")
    public String ssh(String username, String password, String ip, Integer port) throws IOException {
        connType = BaseConst.SSH;
        ftpService = ftpFactory.getFtpService(BaseConst.SSH);
        ftpService.connection(username, password, ip, port);
        return "SFTP connection success!";
    }

    /**
     * 上传文件
     * @param directory
     * @param uploadFile
     * @throws IOException
     */
    @ShellMethod("Input local file and remote dir.")
    public void put(String uploadFile, String directory, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.put(uploadFile, directory, encode);
    }

    @ShellMethod("Input remote filename [and local path].")
    public void get(String filename, @ShellOption(defaultValue="") String localPath, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.get(filename, localPath, encode);
    }

    @ShellMethod("Input local file and remote dir.")
    public void scpPut(String uploadFile, String directory, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.scpPut(uploadFile, directory, encode);
    }

    @ShellMethod("Input remote filename [and local path].")
    public void scpGet(String filename, @ShellOption(defaultValue="") String localPath, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.scpGet(filename, localPath, encode);
    }

    @ShellMethod("Input remote filePath.")
    public void rm(String filePath, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.rm(filePath, encode);
    }

    @ShellMethod("Input remote dir.")
    public void cd(String directory, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.cd(directory, encode);
    }

    @ShellMethod("Change to parent dir.")
    public void cdup() throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.cdup();
    }

    /**
     * 创建多级目录，（有则切换目录，无则创建目录）
     * @param directory
     * @throws IOException
     */
    @ShellMethod("Input dir or dir path.")
    public void mkdir(String directory, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
        ftpService.mkdir(directory, encode);
    }

    @ShellMethod(value="Print directory files.",key={"ls","ll"})
    public String ls(@ShellOption(defaultValue="")String dir, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return null;
        }
        return ftpService.ls(dir, encode);
    }

    @ShellMethod("Print working directory.")
    public String pwd(@ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return null;
        }
       return ftpService.pwd(encode);
    }

    @ShellMethod("Rename or move remote file.")
    public void mv(String from, String to, @ShellOption(defaultValue="")String encode) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return;
        }
       ftpService.mv(from, to, encode);
    }

    @ShellMethod(value="To close ftp connection.", key={"close","disconnect","logout"})
    public String close() throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return null;
        }
        this.connType = "shell";
        return ftpService.close();
    }

    @ShellMethod(value="Input bash cmdLine", key={"bash","shell","cmd","sh"})
    public String bash(String cmdLine) throws IOException {
        if(connType == null) {
            System.err.println("no connection!");
            return null;
        }
        return ftpService.bash(cmdLine);
    }

    @Override
    public AttributedString getPrompt() {
        if (connType != null) {
            return new AttributedString(connType + ":>",
                    AttributedStyle.DEFAULT.foreground(AttributedStyle.YELLOW));
        } else {
            return new AttributedString("shell:>",
                    AttributedStyle.DEFAULT.foreground(AttributedStyle.RED));
        }
    }
}
